{-# LANGUAGE ExistentialQuantification  #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Language.Dependencies.Language
-- Copyright   :  (c) 2009--2010 TU Dortmund
-- License     :  BSD3
--
-- Maintainer  :  menge@udo.cs.uni-dortmund.de
-- Stability   :  experimental
-- Portability :  non-portable
--
-- Contains the main interface of tools like "depedit" to a supported language.
-- Specific values for languages can be found under Adaptors. 
-----------------------------------------------------------------------------

module Language.Dependencies.Language where

import Data.Tree (Tree(..))

-- | Specifies a language. The type variable 'a' is hidden in the value using forall quantification. We cannot access it from outside.
data Language = forall a s phi. Language
  { name :: String -- ^ language name
  , syntax :: String -- ^ syntax highlighter name
  , exts :: [String] -- ^ file extentions
  , parse :: String -> Either Error a -- ^ parse function
  , toTree :: a -> Tree String -- to tree
  , srcLoc :: Tree String -> [Loc]
    -- ^ selector function for source locations (if supported)
  , adjustSrcLoc :: Maybe (s -> s)
    -- ^ adjust src locs in abstract syntax tree (if necessary)
  , srcLoctype :: Loc 
   -- ^ flag for type of source location, values may be undefinded 
  , typerep :: Maybe (phi a)
  }


instance Eq (Language) where
  l1 == l2 = name l1 == name l2

instance Show (Language) where
  show = name 

-- | Specifies parse errors.
data Error
  = Err                    -- ^ no error information
  | ErrMessage String      -- ^ simple error message
  | ErrLocation Loc String -- ^ error message and src loc
  deriving Show
    
-- | Specifies a source location by either an offset or coordinates.
data Loc = OffSet Int Int                 -- ^ (from,to)
         | Coordinate (Int,Int) (Int,Int) -- ^ from@(line,column) to@(line,column)
         deriving (Eq,Show)

-- | A src location is smaller than another one iff the first one includes 
-- the second one 
instance Ord Loc where
  (OffSet i1 i2) <= (OffSet j1 j2) = i1 >= j1 && j2 >= i2
  (Coordinate i1 i2) <= (Coordinate j1 j2) = i1 <= j1 && j2 <= i2  
  _ <= _ = False           
            
